/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* includes (local) ----------------------------------------------------------*/
#include <pony/lcd/lcd.h>
#include <pony/lcd/lcd_font.h>
/* includes (standard library, system) ---------------------------------------*/
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/

/* defines -------------------------------------------------------------------*/
/* typedefs ------------------------------------------------------------------*/
/* macro ---------------------------------------------------------------------*/
/* variables (extern) --------------------------------------------------------*/
/* variables (local) ---------------------------------------------------------*/
/* variables (global) --------------------------------------------------------*/
/* inlines -------------------------------------------------------------------*/
/* functions -----------------------------------------------------------------*/

/**
 * lcd_show_char - show a char
 * @lcd: lcd device
 * @x: x position
 * @y: y position
 * @num: char
 * @fc: front color
 * @bc: back color
 * @sizey: font size (12, 16, 24, 32)
 * @mode: 0, fill; 1, draw
 *
 * @retval None
 */
void lcd_show_char(hal_lcd_t *lcd, uint32_t x, uint32_t y, uint8_t num, uint32_t fc, uint32_t bc,
                   uint8_t sizey, uint8_t mode)
{
    uint8_t tmp, sizex, t, m = 0;
    uint32_t i, type_face_num;
    uint32_t x0 = x;
    sizex = sizey / 2;
    type_face_num = (sizex / 8 + ((sizex % 8) ? 1 : 0)) * sizey;
    num = num - ' ';

    for (i = 0; i < type_face_num; i++) {
        if (sizey == 12)
            tmp = lcd_font_ascii_1206[num][i];
        else if (sizey == 16)
            tmp = lcd_font_ascii_1608[num][i];
        else if (sizey == 24)
            tmp = lcd_font_ascii_2412[num][i];
        else if (sizey == 32)
            tmp = lcd_font_ascii_3216[num][i];
        else
            return;
        for (t = 0; t < 8; t++) {
            if (!mode) {
                if (tmp & (0x01 << t))
                    hal_lcd_draw_point(lcd, x, y, fc);
                else
                    hal_lcd_draw_point(lcd, x, y, bc);
                m++;
                x++;
                if (m % sizex == 0) {
                    m = 0;
                    y++;
                    break;
                }
            } else {
                if (tmp & (0x01 << t))
                    hal_lcd_draw_point(lcd, x, y, fc);
                x++;
                if ((x - x0) == sizex) {
                    x = x0;
                    y++;
                    break;
                }
            }
        }
    }
}

/**
 * lcd_show_string - show a string
 * @lcd: lcd device
 * @x: x position
 * @y: y position
 * @p: string
 * @fc: front color
 * @bc: back color
 * @sizey: font size (12, 16, 24, 32)
 * @mode: 0, fill; 1, draw
 *
 * @retval None
 */
void lcd_show_string(hal_lcd_t *lcd, uint32_t x, uint32_t y, const uint8_t *p, uint32_t fc,
                     uint32_t bc, uint8_t sizey, uint8_t mode)
{
    while (*p != '\0') {
        lcd_show_char(lcd, x, y, *p, fc, bc, sizey, mode);
        x += sizey / 2;
        p++;
    }
}

static uint32_t __pow(uint8_t m, uint8_t n)
{
    uint32_t result = 1;
    while (n--)
        result *= m;
    return result;
}

/**
 * lcd_show_int_num - show a integer number
 * @lcd: lcd device
 * @x: x position
 * @y: y position
 * @num: number
 * @len: number length
 * @fc: front color
 * @bc: back color
 * @sizey: font size (12, 16, 24, 32)
 *
 * @retval None
 */
void lcd_show_int_num(hal_lcd_t *lcd, uint32_t x, uint32_t y, uint32_t num, uint8_t len,
                      uint32_t fc, uint32_t bc, uint8_t sizey)
{
    uint8_t t, temp;
    uint8_t enshow = 0;
    uint8_t sizex = sizey / 2;
    for (t = 0; t < len; t++) {
        temp = (num / __pow(10, len - t - 1)) % 10;
        if (enshow == 0 && t < (len - 1)) {
            if (temp == 0) {
                lcd_show_char(lcd, x + t * sizex, y, ' ', fc, bc, sizey, 0);
                continue;
            } else
                enshow = 1;
        }
        lcd_show_char(lcd, x + t * sizex, y, temp + 48, fc, bc, sizey, 0);
    }
}

/**
 * lcd_show_float_num - show a float number
 * @lcd: lcd device
 * @x: x position
 * @y: y position
 * @num: number
 * @len: number length
 * @fc: front color
 * @bc: back color
 * @sizey: font size (12, 16, 24, 32)
 *
 * @retval None
 */
void lcd_show_float_num(hal_lcd_t *lcd, uint32_t x, uint32_t y, float num, uint8_t len, uint32_t fc,
                        uint32_t bc, uint8_t sizey)
{
    uint8_t t, temp, sizex;
    uint32_t num1;
    sizex = sizey / 2;
    num1 = num * 100;
    for (t = 0; t < len; t++) {
        temp = (num1 / __pow(10, len - t - 1)) % 10;
        if (t == (len - 2)) {
            lcd_show_char(lcd, x + (len - 2) * sizex, y, '.', fc, bc, sizey, 0);
            t++;
            len += 1;
        }
        lcd_show_char(lcd, x + t * sizex, y, temp + 48, fc, bc, sizey, 0);
    }
}
